package top.suven.base.util;

import top.suven.base.util.constants.Env;
import top.suven.base.util.constants.PropertiesParam;
import top.suven.base.util.utilize.Base64Util;
import com.google.common.collect.ImmutableSet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;

@Component
public class FileUploadHelper {
	
	private Logger logger = LoggerFactory.getLogger(getClass());
	
	/** 上传文件缓存的父路径*/

    public String UPLOAD_PARENT_PATH = PropertiesParam.gc_dl_upload_url();

    /** 上传 的块的大小   单位 字节 */
	//public final static long WIFI = 100 * 1024 ;
	public final static long WIFI = PropertiesParam.gc_dl_upload_wifi_size() ;

	//public final static long G2G3 = 50 * 1024 ;
	public final static long G2G3 = PropertiesParam.gc_dl_upload_g2g3_size() ;

	/** 上传字节的限制,单位字节*/
	public final static long UPLOAD_IMG_SIZE_LIMIT = PropertiesParam.gc_dl_upload_img_size_limit();
	
	/** 上传字节的限制,单位字节*/
	public final static long UPLOAD_RECORD_SIZE_LIMIT = Env.isProd() ? (10L * 1024 * 1024) : (6L * 1024 * 1024);
	
	private static ImmutableSet<String> ALLOWED_FILE_TYPE = ImmutableSet.of("m4a", "mp3", "png", "jpg", "jpeg", "M4A", "MP3", ".PNG", "JPG", "JPEG");
	
	private static ImmutableSet<String> ALLOWED_RECORD_SIZE = ImmutableSet.of("m4a", "mp3", "M4A", "MP3");
	
	/**
	 * 过滤非法文件
	 * @param fileSuffix
	 * @return
	 */
	public static boolean isAllowedFile(String fileSuffix){
		
		return ALLOWED_FILE_TYPE.contains(fileSuffix);
	}
	
	/**
	 * @param fileSuffix
	 * @return
	 */
	public static long allowedFileSize(String fileSuffix){
		
		return ALLOWED_RECORD_SIZE.contains(fileSuffix) ? UPLOAD_RECORD_SIZE_LIMIT : UPLOAD_IMG_SIZE_LIMIT;
	}
	/**
	 * 得到缓存位置
	 * 
	 * @return
	 */
	public File getFileCachePath() {
		File path = new File(UPLOAD_PARENT_PATH);
		if(!path.exists()){
			boolean bool = path.mkdirs();
			logger.info("create path:{}, success:{}", path.getAbsolutePath(), bool);
		}
		return path;
	}
	
	/**
	 * 删除缓存文件
	 * 
	 * @param uuid
	 */
	public void deleteCacheFile(String uuid){
		File file = new File(getFileCachePath(), uuid);
		if(file.exists()){
			file.deleteOnExit();
			logger.info("delete new file:{}", file.getAbsolutePath());
		}
	}
	
	/**
	 * 得到缓存的文件
	 * 
	 * @param customPath
	 * @return
	 */
	public File getCacheFile(String customPath){
		File file = new File(getFileCachePath(), customPath);
		if(!file.getParentFile().exists()){
			try {
				file.getParentFile().mkdirs();
			} catch (Exception e) {
				logger.info("Create new Parent File failed:{}" ,file.getParentFile() );
			}
		}
		if(!file.exists()){
			try {
				file.createNewFile();
				logger.info("Create new file:{}", file.getAbsolutePath());
			} catch (IOException e) {
				logger.info("Create new file failed:{}" , customPath);
			}
		}
		return file;
	}
	
	/**
	 * 追加缓存文件
	 * 返回当前位子
	 * @param uuid
	 * @param filePart
	 * @param position
	 */
	public long cacheFilepart(String uuid , byte[] filePart, long position){
		File file = new File(getFileCachePath(), uuid);
		RandomAccessFile outStream = null;
		try {
			if(file.length() != position){
				return file.length();
			}
			outStream = new RandomAccessFile(file, "rwd");
			outStream.seek(position);
			outStream.write(filePart);
			
		} catch (FileNotFoundException e) {
			logger.error("FileNotFoundException:{}", uuid);
		} catch (IOException e) {
			logger.error("IOException:{}", uuid);
		}finally{
			try {
				if(outStream != null){
					outStream.close();
				}
			} catch (IOException e) {
				logger.error("OutStream close exception:{}", uuid);
			}
		}
		
		return file == null ? 0 : file.length();
	}
	

	/**
	 * 根据网络渠道获取文件块的大小
	 * @return
	 */
	public static long getNetByte(int type){
		switch (type) {
		case 0:
			return WIFI;
		case 1: 
			return G2G3;
		default:
			return WIFI;
		}
	}

	/**
	 * @Title:
	 * @Description: 断点续传保存
	 * @param file:文件地址 start:开始fileData:文件内容
	 * @return
	 * @author liulu
	 * @date 2018/6/6 15:10
	 */
	public boolean uploadFile(String file,int start,String fileData) {
		try {
			String parentPath = new File(file).getParent();
			if(!new File(parentPath).exists()){
				new File(parentPath).mkdirs();
			}

			byte[] fileBytes = Base64Util.decode(fileData);
			logger.info("bytes:"+fileBytes.length);
			for (int i = 0; i < fileBytes.length; ++i) {
				if (fileBytes[i] < 0) {
					// 调整异常数据
					fileBytes[i] += 256;
				}
			}

			RandomAccessFile oSavedFile = new RandomAccessFile(file, "rw");
			oSavedFile.seek(start);
			oSavedFile.write(fileBytes);
			oSavedFile.close();

			return true;
		} catch (Exception e) {
			logger.error("upload file error:"+e.getMessage(),e);
		}
		return false;
	}
	
}
